package com.bbtShop.service;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bbtShop.config.BizException;
import com.bbtShop.core.model.*;
import com.bbtShop.core.utils.*;
import com.bbtShop.dao.*;
import org.apache.commons.codec.digest.Md5Crypt;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

import static com.bbtShop.core.model.SysLoginLog.login;
import static com.bbtShop.core.utils.RedisUtil.fex;

/**
 * @Author manke
 * @Date 2020/10/30 15:15
 * @Version 0.0.1
 */
@Service
public class SysUserService {
    private final static long longTime = 60 * 60;

    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private UserInfoUtil userInfoUtil;
    @Autowired
    HttpServletRequest request;
    @Autowired
    private IpToAddrUtil ipToAddrUtil;

    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private SysRoleMenuMapper sysRoleMenuMapper;
    @Autowired
    private SysMenuMapper sysMenuMapper;
    @Autowired
    private SysLoginLogMapper sysLoginLogMapper;
    @Autowired
    private SysLoginLogViewMapper sysLoginLogViewMapper;
    @Autowired
    private PageUtil pageUtil;

    public String login(SysUser sysUser) {
        String pass = Md5Utils.hash(sysUser.getPassword());
        LambdaQueryWrapper<SysUser> sysUserLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysUserLambdaQueryWrapper.eq(SysUser::getAccount, sysUser.getAccount());
        SysUser sysUserV = sysUserMapper.selectOne(sysUserLambdaQueryWrapper);
        if (sysUserV == null) {
            throw new BizException(ResultCode.ACCOUNT_ERROR);
        }
        if (!sysUserV.getPassword().equals(pass)) {
            throw new BizException(ResultCode.PASSWORD_ERROR);
        }
        //获取服务端token
        String serverToken = redisUtil.get(sysUser.getAccount());
        if (serverToken != null && !"".equals(serverToken)) {
            //存在token  删除上个token
            redisUtil.del(serverToken);
        }
        //生成token
        String token = Md5Utils.hash(String.valueOf(new Date().getTime()));
        //查询角色权限
        String role = sysUserV.getRole();
        //获取角色对应菜单
        List<SysMenu> sysMenus = getSysMenuByRole(role);
        UserInfoDto userInfoDto = new UserInfoDto();
        if (sysMenus != null) {
            LinkedList<String> permissions = new LinkedList<>();
            for (SysMenu sysMenu : sysMenus) {
                permissions.add(sysMenu.getPermissionFlag());
            }
            userInfoDto.setAccount(sysUser.getAccount());
            userInfoDto.setPermission(permissions);
        }

        //token 对应权限
        redisUtil.set(fex + token, JSON.toJSONString(userInfoDto), longTime);

        //用户账号对应token
        redisUtil.set(sysUser.getAccount(), fex + token, longTime);
        return token;
    }

    public void sysLoginLog(SysLoginLog sysLoginLog) {
        sysLoginLogMapper.insert(sysLoginLog);
    }

    public void register(SysUser sysUser) {
        sysUser.setPassword(Md5Utils.hash(sysUser.getPassword()));
        sysUser.setAddTime(new Date());
        sysUserMapper.insert(sysUser);
    }

    public void logout() {
        String token = request.getHeader("token");
        if (token != null && !"".equals(token)) {
            redisUtil.del(fex + token);
        }


    }

    public List<UserMenuTree> getMenu() {
        UserInfoDto userInfo = userInfoUtil.getUserInfo();
        if (userInfo == null) {
            throw new BizException(ResultCode.LOGIN_PAST);
        }
        String account = userInfo.getAccount();
        //根据账号获取登录信息
        LambdaQueryWrapper<SysUser> sysUserQuery = new LambdaQueryWrapper<>();
        sysUserQuery.eq(SysUser::getAccount, account);
        SysUser sysUser = sysUserMapper.selectOne(sysUserQuery);
        String role = sysUser.getRole();
        List<SysMenu> sysMenus = getSysMenuByRole(role);
        LinkedList<UserMenuTree> userMenuTrees = new LinkedList<>();
        for (SysMenu sysMenu : sysMenus) {
            UserMenuTree userMenuTree = new UserMenuTree();
            BeanUtils.copyProperties(sysMenu, userMenuTree);
            userMenuTrees.add(userMenuTree);
        }
        List<UserMenuTree> tree = TreeUtil.tree(userMenuTrees);
        return tree;


    }

    public List<SysMenu> getSysMenuByRole(String role) {
        List<SysRoleMenu> sysRoleMenus = sysRoleMenuMapper.selectList(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getRoleId, role));
        ArrayList<Integer> list = new ArrayList<>();

        for (SysRoleMenu sysRoleMenu : sysRoleMenus) {
            list.add(sysRoleMenu.getMenuId());
        }
        if (list.size() > 0) {
            return sysMenuMapper.selectBatchIds(list);
        }
        return null;


    }

    public Map<String,Object> loginInfo() {

        HashMap<String, Object> map = new HashMap<>();
        UserInfoDto userInfo = userInfoUtil.getUserInfo();
        LambdaQueryWrapper<SysLoginLogView> sys = new LambdaQueryWrapper<>();
        sys.eq(SysLoginLogView::getAccount, userInfo.getAccount());
        sys.orderByDesc(SysLoginLogView::getCreatetime).last("limit 1,1");
        List<SysLoginLogView> sysLoginLogViews = sysLoginLogViewMapper.selectList(sys);
        if (sysLoginLogViews.size()>0){
            map.put("loginInfo",sysLoginLogViews.get(0));
            map.put("now",ipToAddrUtil.Addr(IpUtil.getIpAddr(request)));
            return map;
        }
        return null;
    }
}
